package com.yaodian100.ec.generatepage.web;

import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import javax.imageio.ImageIO;

import org.apache.commons.lang.time.FastDateFormat;
import org.apache.commons.lang.xwork.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.Preparable;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.core.menu.service.MenuService;
import com.yaodian100.ec.common.EcConstant;
import com.yaodian100.ec.generate.entity.EventImage;
import com.yaodian100.ec.generate.entity.GenerateAdvertise;
import com.yaodian100.ec.generate.entity.GenerateContent;
import com.yaodian100.ec.generate.entity.GeneratePosition;
import com.yaodian100.ec.generate.service.GenerateService;
import com.yaodian100.ec.generatepage.entity.IdxImageAdv;

public class IdxImageAdvAction extends AbstractAdvAction implements Preparable {

	private static final String ADV_TYPE_IDX_TWINRIGHT = "IDX_TWINRIGHT";
	private static final String ADV_TYPE_IDX_RIGHTSMALL2 = "IDX_RIGHTSMALL2";
	private static final String ADV_TYPE_IDX_TWINLEFT = "IDX_TWINLEFT";
	private static final String ADV_TYPE_IDX_RIGHTSMALL1 = "IDX_RIGHTSMALL1";
	private static final String ADV_TYPE_IDX_WAISTLINE = "IDX_WAISTLINE";
	private static final String ADV_TYPE_IDX_TOPSPAN = "IDX_TOPSPAN";
	private static final String ADV_TYPE_IDX_HOTSALE_BANNER = "IDX_HOTSALE_BANNER";
	private static final String ADV_TYPE_IDX_WAISTLINE_V5 = "IDX_WAISTLINE_V5";
	private static final String ADV_TYPE_IDX_BANK_BANNER = "IDX_BANK_BANNER";
	
	private static final String ADV_TYPE_PCL_HOTSALE_BANNER = "PCL_HOTSALE_BANNER";
	private static final String ADV_TYPE_PCL_TOPSPAN = "PCL_TOPSPAN";
	private static final String ADV_TYPE_PCL_WAISTLINE_V5 = "PCL_WAISTLINE_V5";
	private static final String ADV_TYPE_PCL_BANK_BANNER = "PCL_BANK_BANNER";
	
	private static final String PROPERTY_NAME_IMAGE_FOLDER_NAME = "imageFolderName";
	private static final String PROPERTY_NAME_IMAGE_FILE_NAME = "imageFileName";
	private static final String PROPERTY_NAME_AD_CODE = "adCode";
	private static final String PROPERTY_NAME_IMAGE_LINK = "imageLink";
	private static final String ADVSTATUS_SUSPEND = "90";
	private static final long serialVersionUID = 1L;
	private static final String FIELD_NAME_END_TIME = "idxImageAdv.endTime";
	private static final String FIELD_NAME_START_TIME = "idxImageAdv.startTime";
	private static final String FIELD_NAME_IMAGE_FILE = "idxImageAdv.imageFile";
	private static final String LINE_SEPARATOR = System.getProperty("line.separator");

	private IdxImageAdv idxImageAdv;
	private Menu idxAdvTypeMenu;
	private boolean doClone;

	@Autowired
	private GenerateService generateService;
	@Autowired
	private MenuService menuService;

	public String newIdxImageAdv() {
		setCreatingNew(true);
		if (this.idxAdvTypeMenu == null) {
			this.idxAdvTypeMenu = this.getIdxAdvMenu();
		}
		
		return INPUT;
	}

	public String editIdxImageAdv() throws IOException {
		if (this.idxAdvTypeMenu == null) {
			this.idxAdvTypeMenu = this.getIdxAdvMenu();
		}
		
		Long advId = getAdvId();
		if (advId == null) {
			advId = getAdv().getId();
		}
		GenerateAdvertise targetAdv = this.generateService.get(advId);
		GenerateContent targetAdvContent = this.generateService.getGenerateContentByAdvId(advId).get(0);
		
		if (targetAdv == null) {
			return LIST_IDX_ADV;
		}

		setAdv(targetAdv);
		setIdxImageAdv(new IdxImageAdv());

		DateFormat dateFormatter = new SimpleDateFormat(EcConstant.PATTERN_DATE);
		DateFormat timeFormatter = new SimpleDateFormat("HH:mm");
		String startDateString = dateFormatter.format(getAdv().getStartDate());
		String startTimeString = timeFormatter.format(getAdv().getStartDate());
		String endDateString = dateFormatter.format(getAdv().getEndDate());
		String endTimeString = dateFormatter.format(getAdv().getEndDate());
		getIdxImageAdv().setStartDate(startDateString);
		getIdxImageAdv().setStartTime(startTimeString);
		getIdxImageAdv().setEndDate(endDateString);
		getIdxImageAdv().setEndTime(endTimeString);

		Properties properties = new Properties();
		Reader reader = new StringReader(targetAdvContent.getContents());
		properties.load(reader);

		getIdxImageAdv().setAdCode(properties.getProperty(PROPERTY_NAME_AD_CODE));
		getIdxImageAdv().setImageLink(properties.getProperty(PROPERTY_NAME_IMAGE_LINK));
		getIdxImageAdv().setSavedImageFileName(properties.getProperty(PROPERTY_NAME_IMAGE_FILE_NAME));
		getIdxImageAdv().setSavedImageFolderName(properties.getProperty(PROPERTY_NAME_IMAGE_FOLDER_NAME));

		return INPUT;
	}

	public String cloneIdxImageAdv() throws IOException {
		doClone = true;
		
		if (this.idxAdvTypeMenu == null) {
			this.idxAdvTypeMenu = this.getIdxAdvMenu();
		}
		
		Long advId = getAdvId();
		if (advId == null) {
			advId = getAdv().getId();
		}
		GenerateAdvertise targetAdv = this.generateService.get(advId);
		GenerateContent targetAdvContent = this.generateService.getGenerateContentByAdvId(advId).get(0);
		
		GenerateAdvertise tmp_targetAdv = new GenerateAdvertise();
		BeanUtils.copyProperties(targetAdv, tmp_targetAdv, new String[] {"id", "createDate", "createUser", "modifyUser", "modifyDate"});
		targetAdv = tmp_targetAdv;
		
		GenerateContent tmp_targetAdvContent = new GenerateContent();
		BeanUtils.copyProperties(targetAdvContent, tmp_targetAdvContent, new String[] {"id", "advId", "createDate", "createUser", "modifyUser", "modifyDate"});
		targetAdvContent = tmp_targetAdvContent;

		if (targetAdv == null) {
			return LIST_IDX_ADV;
		}

		setAdv(targetAdv);
		setIdxImageAdv(new IdxImageAdv());

		DateFormat dateFormatter = new SimpleDateFormat(EcConstant.PATTERN_DATE);
		DateFormat timeFormatter = new SimpleDateFormat("HH:mm");
		String startDateString = dateFormatter.format(getAdv().getStartDate());
		String startTimeString = timeFormatter.format(getAdv().getStartDate());
		String endDateString = dateFormatter.format(getAdv().getEndDate());
		String endTimeString = dateFormatter.format(getAdv().getEndDate());
		getIdxImageAdv().setStartDate(startDateString);
		getIdxImageAdv().setStartTime(startTimeString);
		getIdxImageAdv().setEndDate(endDateString);
		getIdxImageAdv().setEndTime(endTimeString);

		Properties properties = new Properties();
		Reader reader = new StringReader(targetAdvContent.getContents());
		properties.load(reader);

		getIdxImageAdv().setAdCode(properties.getProperty(PROPERTY_NAME_AD_CODE));
		getIdxImageAdv().setImageLink(properties.getProperty(PROPERTY_NAME_IMAGE_LINK));
		getIdxImageAdv().setSavedImageFileName(properties.getProperty(PROPERTY_NAME_IMAGE_FILE_NAME));
		getIdxImageAdv().setSavedImageFolderName(properties.getProperty(PROPERTY_NAME_IMAGE_FOLDER_NAME));
		
		advId = null;
		
		return INPUT;
	}

	public String saveIdxImageAdv() throws Exception {
		GenerateContent advertiseContent;
		GeneratePosition generatePosition;
		StringBuffer contentBuffer = new StringBuffer();

		Long advertiseId = getAdv().getId();
		if (creatingNewAdv()) {
			advertiseContent = new GenerateContent();
			generatePosition = new GeneratePosition();
		} else {
			advertiseContent = this.generateService.getGenerateContentByAdvId(advertiseId).get(0);
			generatePosition = generateService.getGeneratePositionByAdvId(advertiseId).get(0);
		}

		// 起迄日期
		String dateTimePattern = EcConstant.PATTERN_TIMESTAMP_HH_MM;
		DateFormat formatter = new SimpleDateFormat(dateTimePattern);

		String startDateString = this.idxImageAdv.getStartDate();
		String startTimeString = this.idxImageAdv.getStartTime();
		
		if (StringUtils.isBlank(getAdv().getAdvName())) {
			addFieldError("idxImageAdv.name", "请输入广告名称");
		}
		
		if (startDateString != null) {
			if (startTimeString == null) {
				startTimeString = "00:00";
			}
			String startTimePointString = startDateString + " " + startTimeString;
			try {
				Date startTimePoint = formatter.parse(startTimePointString);
				getAdv().setStartDate(startTimePoint);
			} catch (ParseException e) {
				addFieldError(FIELD_NAME_START_TIME, "起始日期或时间格式不正碉");
			}
		}
		
		String endDateString = this.idxImageAdv.getEndDate();
		String endTimeString = this.idxImageAdv.getEndTime();
		String endTimePointString = endDateString + " " + endTimeString;
		if (endDateString != null) {
			if (endTimeString == null) {
				endTimeString = "23:59";
			}
			try {
				Date endTimePoint = formatter.parse(endTimePointString);
				getAdv().setEndDate(endTimePoint);
			} catch (ParseException e) {
				addFieldError(FIELD_NAME_END_TIME, "结束日期或时间格式不正碉");
			}
		}
		
		// 檢查圖檔
		File imageFile = this.idxImageAdv.getImageFile();
		if (imageFile == null) {
			// 新增時一定要上傳圖片
			if (creatingNewAdv() && !doClone) {
				addFieldError(FIELD_NAME_IMAGE_FILE, "请选择上传图片");
			}
		} else {
			if (!imageFileSizeWithinLimit(imageFile)) {
				addFieldError(FIELD_NAME_IMAGE_FILE, "档案大小超过限制");
			}
			if (!imageFileHeightWidthFit(imageFile)) {
				addFieldError(FIELD_NAME_IMAGE_FILE, "图片长度／宽度不符");
			}
		}
		
		if (!hasErrors()) {
			// 圖片連結
			String imageLink = this.idxImageAdv.getImageLink();
			appendPropertyAndLineBreakToContentBuffer(contentBuffer, PROPERTY_NAME_IMAGE_LINK, imageLink);
			
			// 圖片連結 ad 參數
			String adCode = this.idxImageAdv.getAdCode();
			appendPropertyAndLineBreakToContentBuffer(contentBuffer, PROPERTY_NAME_AD_CODE, adCode);
			
			// 上傳圖檔
			String advType = getAdv().getAdvType();
			String fileName = this.idxImageAdv.getImageFileFileName();
			if (imageFile != null) {
				boolean dirMakeResult = GenerateHelper.mkDir(advType);
				if (!dirMakeResult) {
					getAdv().setAdvStatus(ADVSTATUS_SUSPEND);
					addActionError("图档目录建立失败");
				}
				boolean imageSaveResult = saveImgFileAndAddContentAndSetSavedFileFolderName(imageFile, fileName, advType,
						contentBuffer);
				if (!imageSaveResult) {
					getAdv().setAdvStatus(ADVSTATUS_SUSPEND);
					addActionError("图档上传失败");
				}

			} else {
				// 修改的時候，沒有上傳新圖檔，就回存舊參數
				String propertyNameImageFileName = PROPERTY_NAME_IMAGE_FILE_NAME;
				String propertyNameImageFolderName = PROPERTY_NAME_IMAGE_FOLDER_NAME;
				String imageFileName;
				String imageFolderName;
				imageFileName = this.idxImageAdv.getSavedImageFileName();
				imageFolderName = this.idxImageAdv.getSavedImageFolderName();
				contentBuffer.append(propertyNameImageFileName + "=").append(imageFileName).append(LINE_SEPARATOR);
				contentBuffer.append(propertyNameImageFolderName + "=").append(imageFolderName).append(LINE_SEPARATOR);
			}
			
			// 寫入db
			advertiseContent.setContents(contentBuffer.toString());
			if (creatingNewAdv()) {
				this.generateService.saveGenerateCombine(getAdv(), generatePosition, advertiseContent);
			} else {
				GenerateAdvertise advInDb = this.generateService.get(advertiseId);
				BeanUtils.copyProperties(getAdv(), advInDb, baseEntityPropertiesNames);
				this.generateService.updateGenerateCombine(advInDb, generatePosition, advertiseContent);
			}
			
			if("PCL".equals(this.getFrom())) {
				this.generateService.generateIdxImageAdv(advType, getAdvType2());
			} else {
				this.generateService.generateIdxImageAdv(advType);
			}
			addActionMessage("储存成功");
		} else {
			return INPUT;
		}
		
		setCreatingNew(false);
		return RESULT_VIEW;
	}
	
	public String displaySavedAdv() throws IOException {
		addActionMessage("储存成功");
		return editIdxImageAdv();
	}

	@Override
	public void prepare() throws Exception {
		super.prepare();
		clearActionErrors();
	}

	// public Dimension getImageDimensionLimit() {
	// Dimension dimensionLimit = new Dimension();
	//
	// String advType = getAdv().getAdvType();
	// if (advType.equals(ADV_TYPE_IDX_TOPSPAN)) {
	// dimensionLimit.setSize(950, 50);
	// } else if (advType.equals(ADV_TYPE_IDX_WAISTLINE)) {
	// dimensionLimit.setSize(675, 120);
	// } else if (advType.equals(ADV_TYPE_IDX_RIGHTSMALL1) || advType.equals(ADV_TYPE_IDX_RIGHTSMALL2)) {
	// dimensionLimit.setSize(258, 96);
	// } else if (advType.equals(ADV_TYPE_IDX_TWINLEFT) || advType.equals(ADV_TYPE_IDX_TWINRIGHT)) {
	// dimensionLimit.setSize(330, 80);
	// } else {
	// dimensionLimit.setSize(0, 0);
	// }
	// return dimensionLimit;
	// }

	public int getImageHeightLimit() {
		int result = 0;

		String advType = getAdv().getAdvType();
		if (advType.equals(ADV_TYPE_IDX_TOPSPAN) || advType.equals(ADV_TYPE_PCL_TOPSPAN)) {// 頭部通欄
			result = 50;
		} else if (advType.equals(ADV_TYPE_IDX_WAISTLINE)) {// 腰線
			result = 120;
		} else if (advType.equals(ADV_TYPE_IDX_RIGHTSMALL1) || advType.equals(ADV_TYPE_IDX_RIGHTSMALL2)) {// 右側小廣告
			result = 96;
		} else if (advType.equals(ADV_TYPE_IDX_TWINLEFT) || advType.equals(ADV_TYPE_IDX_TWINRIGHT)) {// 雙拼廣告
			result = 80;
		} else if (advType.equals(ADV_TYPE_IDX_HOTSALE_BANNER) || advType.equals(ADV_TYPE_PCL_HOTSALE_BANNER) ) {// 热销banner
			result = 100;
		} else if (advType.equals(ADV_TYPE_IDX_WAISTLINE_V5) || advType.equals(ADV_TYPE_PCL_WAISTLINE_V5)) {// 大腰带banner V5
			result = 115;
		} else if (advType.equals(ADV_TYPE_IDX_BANK_BANNER) || advType.equals(ADV_TYPE_PCL_BANK_BANNER)) {// 银行分期banner
			result = 245;
		} else {
			result = 0;
		}
		return result;
	}

	public int getImageWidthLimit() {
		int result = 0;

		String advType = getAdv().getAdvType();
		if (advType.equals(ADV_TYPE_IDX_TOPSPAN) || advType.equals(ADV_TYPE_PCL_TOPSPAN)) {// 頭部通欄
			result = 950;
		} else if (advType.equals(ADV_TYPE_IDX_WAISTLINE)) {// 腰線
			result = 675;
		} else if (advType.equals(ADV_TYPE_IDX_RIGHTSMALL1) || advType.equals(ADV_TYPE_IDX_RIGHTSMALL2)) {// 右側小廣告
			result = 258;
		} else if (advType.equals(ADV_TYPE_IDX_TWINLEFT) || advType.equals(ADV_TYPE_IDX_TWINRIGHT)) {// 雙拼廣告
			result = 330;
		} else if (advType.equals(ADV_TYPE_IDX_HOTSALE_BANNER) || advType.equals(ADV_TYPE_PCL_HOTSALE_BANNER)) {// 热销banner
			result = 675;
		} else if (advType.equals(ADV_TYPE_IDX_WAISTLINE_V5) || advType.equals(ADV_TYPE_PCL_WAISTLINE_V5)) {// 大腰带banner V5
			result = 948;
		} else if (advType.equals(ADV_TYPE_IDX_BANK_BANNER) || advType.equals(ADV_TYPE_PCL_BANK_BANNER)) {// 银行分期banner
			result = 260;
		} else {
			result = 0;
		}
		return result;
	}

	public int getFileSizeLimitK() {
		int fileSizeLimitK;

		String advType = getAdv().getAdvType();
		if (advType.equals(ADV_TYPE_IDX_TOPSPAN) || advType.equals(ADV_TYPE_PCL_TOPSPAN)) {// 頭部通欄
			fileSizeLimitK = 20;
		} else if (advType.equals(ADV_TYPE_IDX_WAISTLINE)) {// 腰線
			fileSizeLimitK = 40;
		} else if (advType.equals(ADV_TYPE_IDX_RIGHTSMALL1) || advType.equals(ADV_TYPE_IDX_RIGHTSMALL2)) {// 右側小廣告
			fileSizeLimitK = 12;
		} else if (advType.equals(ADV_TYPE_IDX_TWINLEFT) || advType.equals(ADV_TYPE_IDX_TWINRIGHT)) {// 雙拼廣告
			fileSizeLimitK = 20;
		} else if (advType.equals(ADV_TYPE_IDX_HOTSALE_BANNER) || advType.equals(ADV_TYPE_PCL_HOTSALE_BANNER)) {// 热销banner
			fileSizeLimitK = 25;
		} else if (advType.equals(ADV_TYPE_IDX_WAISTLINE_V5) || advType.equals(ADV_TYPE_PCL_WAISTLINE_V5)) {// 大腰带banner V5
			fileSizeLimitK = 30;
		} else if (advType.equals(ADV_TYPE_IDX_BANK_BANNER) || advType.equals(ADV_TYPE_PCL_BANK_BANNER)) {// 银行分期banner
			fileSizeLimitK = 20;
		} else {
			fileSizeLimitK = 0;
		}
		return fileSizeLimitK;
	}
	
	public String getAdvType2() {
		String advType2 = "";
		String advType = getAdv().getAdvType();
		if(advType.equals(ADV_TYPE_PCL_TOPSPAN)) {
			advType2 = ADV_TYPE_IDX_TOPSPAN;
		} else if(advType.equals(ADV_TYPE_PCL_HOTSALE_BANNER)) {
			advType2 = ADV_TYPE_IDX_HOTSALE_BANNER;
		} else if(advType.equals(ADV_TYPE_PCL_WAISTLINE_V5)) {
			advType2 = ADV_TYPE_IDX_WAISTLINE_V5;
		} else if(advType.equals(ADV_TYPE_PCL_BANK_BANNER)) {
			advType2 = ADV_TYPE_IDX_BANK_BANNER;
		}
		return advType2;
	}
	
	private Menu getIdxAdvMenu(){
		Menu ruselt;
		if("PCL".equals(this.getFrom())) {
			ruselt = this.menuService.get("Generate.AdvPclTypeV5");
		} else if ("V5".equals(this.getFrom())) {
			ruselt = this.menuService.get("Generate.AdvIdxTypeV5");
		}else{
			ruselt = this.menuService.get("Generate.AdvIdxType");
		}
		
		return ruselt;
	}

	private boolean creatingNewAdv() {
		return getAdv().getId() == null;
	}

	public IdxImageAdv getIdxImageAdv() {
		return this.idxImageAdv;
	}

	public void setIdxImageAdv(IdxImageAdv idxImageAdv) {
		this.idxImageAdv = idxImageAdv;
	}

	public GenerateService getGenerateService() {
		return this.generateService;
	}

	public void setGenerateService(GenerateService generateService) {
		this.generateService = generateService;
	}

	public MenuService getMenuService() {
		return this.menuService;
	}

	public void setMenuService(MenuService menuService) {
		this.menuService = menuService;
	}

	public Menu getIdxAdvTypeMenu() {
		return this.idxAdvTypeMenu;
	}

	public void setIdxAdvTypeMenu(Menu idxAdvTypeMenu) {
		this.idxAdvTypeMenu = idxAdvTypeMenu;
	}

	// ========== private members ==========

	private boolean imageFileSizeWithinLimit(File imgFile) {
		double fileSizeLimitK = getFileSizeLimitK();

		if (null == imgFile) {
			return true;
		}
		if ((imgFile.length() / 1024) > fileSizeLimitK) {
			return false;
		}
		return true;
	}

	private boolean imageFileHeightWidthFit(File imgFile) throws IOException {
		int widthLimit = getImageWidthLimit();
		int heightLimit = getImageHeightLimit();
		return imageFileHeightWidthFit(imgFile, widthLimit, heightLimit);
	}

	private boolean imageFileHeightWidthFit(File imgFile, int fileWidth, int fileHeight) throws IOException {
		if (imgFile == null) {
			return true;
		}
		Image image = ImageIO.read(imgFile);
		if (image.getHeight(null) != fileHeight || image.getWidth(null) != fileWidth) {
			return false;
		}
		return true;
	}

	private boolean saveImgFileAndAddContentAndSetSavedFileFolderName(File imgFile, String fileName, String advType,
			StringBuffer contentBuffer) {
		String propertyNameImageFileName = PROPERTY_NAME_IMAGE_FILE_NAME;
		String propertyNameImageFolderName = PROPERTY_NAME_IMAGE_FOLDER_NAME;
		String imageFileName;
		String imageFolderName;
		if (imgFile == null) {
			imageFileName = this.idxImageAdv.getSavedImageFileName();
			imageFolderName = this.idxImageAdv.getSavedImageFolderName();
		} else {
			EventImage eventImage = new EventImage();
			String today = FastDateFormat.getInstance(EcConstant.DEFAULT_PATTERN_DATE).format(DateUtil.getToday().getTime());

			eventImage = new EventImage();
			eventImage.setImgType(fileName.substring(fileName.lastIndexOf("."), fileName.length()));
			eventImage = this.generateService.saveEventImage(eventImage);
			boolean uploadSuccess = GenerateHelper.uploadImage(eventImage, imgFile, advType);
			if (!uploadSuccess) {
				return false;
			}
			imageFileName = eventImage.getUuid() + eventImage.getImgType();
			imageFolderName = today;

			this.idxImageAdv.setSavedImageFileName(imageFileName);
			this.idxImageAdv.setSavedImageFolderName(imageFolderName);
		}
		contentBuffer.append(propertyNameImageFileName + "=").append(imageFileName).append(LINE_SEPARATOR);
		contentBuffer.append(propertyNameImageFolderName + "=").append(imageFolderName).append(LINE_SEPARATOR);

		return true;
	}

	public boolean isDoClone() {
		return doClone;
	}

	public void setDoClone(boolean doClone) {
		this.doClone = doClone;
	}

}
